const express = require('express');
const dgram = require('dgram');
const cors = require('cors');
const { Sequelize, Op } = require('sequelize');
const sequelize = require('./config/database');
const User = require('./models/User');
const Message = require('./models/Message');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const updateConfig = require('./config/update.json');
const Moment = require('./models/Moment');

const app = express();
const udpServer = dgram.createSocket('udp4');
const PORT = 3000;
const UDP_PORT = 10000;

// 配置图片上传存储
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        const uploadDir = 'uploads/';
        if (!fs.existsSync(uploadDir)) {
            fs.mkdirSync(uploadDir);
        }
        cb(null, uploadDir);
    },
    filename: function (req, file, cb) {
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
        cb(null, uniqueSuffix + path.extname(file.originalname));
    }
});

// 配置图片上传
const imageUpload = multer({ 
    storage: storage,
    limits: {
        fileSize: 20 * 1024 * 1024 // 限制20MB
    },
    fileFilter: function (req, file, cb) {
        if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
            return cb(new Error('只允许上传图片文件!'));
        }
        cb(null, true);
    }
});

// 配置音频上传
const audioUpload = multer({
    storage: storage,
    limits: {
        fileSize: 5 * 1024 * 1024 // 限制5MB
    },
    fileFilter: function (req, file, cb) {
        if (!file.originalname.match(/\.(m4a|mp3|wav)$/)) {
            return cb(new Error('只允许上传音频文件!'));
        }
        cb(null, true);
    }
});

// 配置文件上传
const fileUpload = multer({
    storage: storage,
    limits: {
        fileSize: 100 * 1024 * 1024 // 限制100MB
    }
});

// 配置视频上传
const videoUpload = multer({
    storage: storage,
    limits: {
        fileSize: 50 * 1024 * 1024 // 限制50MB
    },
    fileFilter: function (req, file, cb) {
        if (!file.originalname.match(/\.(mp4|avi|mov|wmv|flv|mkv)$/)) {
            return cb(new Error('只允许上传视频文件!'));
        }
        cb(null, true);
    }
});

app.use(cors());
app.use(express.json());
app.use('/uploads', express.static('uploads')); // 静态文件服务

// 数据库关联
User.hasMany(Message, { foreignKey: 'senderId', as: 'sentMessages' });
User.hasMany(Message, { foreignKey: 'receiverId', as: 'receivedMessages' });
Message.belongsTo(User, { foreignKey: 'senderId', as: 'sender' });
Message.belongsTo(User, { foreignKey: 'receiverId', as: 'receiver' });

// UDP服务器处理
udpServer.on('message', async (msg, rinfo) => {
    try {
        const message = JSON.parse(msg.toString());
        console.log('\n收到新消息:', message);

        // 更新发送者的IP和端口
        let sender = null;
        try {
            sender = await User.findByPk(message.senderId);
            if (sender) {
                const now = new Date();
                now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
                await sender.update({
                    ip: rinfo.address,
                    port: rinfo.port,
                    lastSeen: now.toISOString()
                });
            }
        } catch (error) {
            console.error('更新发送者信息失败:', error);
        }

        // 如果是心跳消息，返回心跳回执
        if (message.type === 'HEARTBEAT') {
            console.log('收到心跳消息，发送回执');
            const heartbeatAck = {
                content: "heartbeat_ack",
                senderId: -1,
                receiverId: message.senderId,
                type: "HEARTBEAT_ACK",
                timestamp: new Date().toISOString()
            };
            udpServer.send(JSON.stringify(heartbeatAck), rinfo.port, rinfo.address, (err) => {
                if (err) {
                    console.error('发送心跳回执失败:', err);
                } else {
                    console.log('心跳回执已发送');
                }
            });
            return;
        }

        // 如果是已读回执消息，更新原消息的已读状态
        if (message.type === 'READ_RECEIPT') {
            try {
                // 查找原消息
                const originalMessage = await Message.findByPk(parseInt(message.content));
                if (!originalMessage) {
                    console.error('找不到原始消息:', message.content);
                    return;
                }

                // 验证接收者身份
                if (originalMessage.receiverId !== message.senderId) {
                    console.error('无效的已读回执：接收者身份不匹配');
                    return;
                }

                // 更新消息的已读状态
                await originalMessage.update({
                    isRead: true,
                    readTime: new Date()
                });

                console.log('消息已标记为已读:', message.content);
                return;
            } catch (error) {
                console.error('处理已读回执时出错:', error);
                return;
            }
        }

        // 查找接收者
        let receiver = null;
        try {
            receiver = await User.findByPk(message.receiverId);
        } catch (error) {
            console.error('查找接收者失败:', error);
        }

        // 保存消息到数据库
        if (message.type === 'RECALLED') {
            // 处理消息撤回
            try {
                // 查找原消息
                const originalMessage = await Message.findByPk(message.id);
                if (!originalMessage) {
                    console.error('找不到要撤回的原始消息:', message.id);
                    return;
                }

                // 验证发送者身份
                if (originalMessage.senderId !== message.senderId) {
                    console.error('无权撤回他人的消息');
                    return;
                }

                // 检查撤回时间限制（2分钟）
                const now = new Date();
                const messageTime = new Date(originalMessage.timestamp);
                const timeDiff = now - messageTime;
                if (timeDiff > 2 * 60 * 1000) {
                    console.error('消息发送超过2分钟，无法撤回');
                    return;
                }

                // 更新消息状态为已撤回
                await originalMessage.update({
                    type: 'RECALLED',
                    updatedAt: now.toISOString()
                });

                console.log('消息已撤回:', message.id);
            } catch (error) {
                console.error('处理撤回消息时出错:', error);
            }
        }

        // 保存新消息
        try {
            // 确保时间戳是有效的 ISO 8601 格式
            let timestamp = message.timestamp;
            if (!timestamp) {
                timestamp = new Date().toISOString();
            } else if (typeof timestamp === 'number' || /^\d+$/.test(timestamp)) {
                timestamp = new Date(parseInt(timestamp)).toISOString();
            } else if (!timestamp.includes('T')) {
                // 如果不是标准的 ISO 8601 格式，尝试转换
                timestamp = new Date(timestamp).toISOString();
            }

            const messageData = {
                content: message.content,
                senderId: message.senderId,
                receiverId: message.receiverId,
                type: message.type || 'TEXT',
                timestamp: timestamp,
                isDelivered: false
            };

            // 如果是图片消息，添加imageUrl字段
            if (message.type === 'IMAGE') {
                messageData.imageUrl = message.imageUrl;
                console.log('图片消息URL:', message.imageUrl);
            }

            // 如果是语音消息，添加audioUrl和audioDuration字段
            if (message.type === 'AUDIO') {
                messageData.audioUrl = message.audioUrl;
                messageData.audioDuration = message.audioDuration;
                console.log('语音消息数据:', {
                    audioUrl: message.audioUrl,
                    audioDuration: message.audioDuration
                });
            }

            // 如果是文件消息，添加文件相关字段
            if (message.type === 'FILE') {
                messageData.fileUrl = message.fileUrl;
                messageData.fileName = message.fileName;
                messageData.fileSize = message.fileSize;
                console.log('文件消息数据:', {
                    fileUrl: message.fileUrl,
                    fileName: message.fileName,
                    fileSize: message.fileSize
                });
            }

            // 如果是视频消息，添加视频相关字段
            if (message.type === 'VIDEO') {
                messageData.videoUrl = message.videoUrl;
                messageData.videoDuration = message.videoDuration;
                messageData.videoThumbnail = message.videoThumbnail;
                console.log('视频消息数据:', {
                    videoUrl: message.videoUrl,
                    videoDuration: message.videoDuration,
                    videoThumbnail: message.videoThumbnail
                });
            }

            // 如果是引用消息，添加引用相关字段
            if (message.type === 'QUOTE') {
                messageData.quotedMessageId = message.quotedMessageId;
                messageData.quotedContent = message.quotedContent;
                messageData.quotedSenderName = message.quotedSenderName;
                console.log('引用消息数据:', {
                    quotedMessageId: message.quotedMessageId,
                    quotedContent: message.quotedContent,
                    quotedSenderName: message.quotedSenderName
                });
            }
            
            const savedMessage = await Message.create(messageData);
            message.id = savedMessage.id;
            console.log('消息已保存，ID:', savedMessage.id);

            // 如果接收者在线，转发消息
            if (receiver && receiver.ip && receiver.port) {
                udpServer.send(JSON.stringify(message), receiver.port, receiver.ip, (err) => {
                    if (err) {
                        console.error('转发消息失败:', err);
                    } else {
                        console.log('消息已转发给接收者');
                    }
                });
            }
        } catch (error) {
            console.error('保存消息时出错:', error);
        }
    } catch (error) {
        console.error('处理消息时出错:', error);
    }
});

// API路由
app.get('/api/users', async (req, res) => {
    try {
        const users = await User.findAll({
            attributes: ['id', 'username', 'lastSeen'],
            order: [['lastSeen', 'DESC']]
        });
        console.log('获取用户列表成功，共 ' + users.length + ' 个用户');
        res.json(users);
    } catch (error) {
        console.error('获取用户列表失败:', error);
        res.status(500).json({ error: error.message });
    }
});

app.post('/api/users/register', async (req, res) => {
    try {
        const user = await User.create(req.body);
        console.log('新用户注册成功:', user.username, 'ID:', user.id);
        res.json(user);
    } catch (error) {
        console.error('注册失败:', error);
        res.status(400).json({ error: error.message });
    }
});

app.post('/api/users/login', async (req, res) => {
    try {
        const { username, password } = req.body;
        const user = await User.findOne({ where: { username } });
        if (!user) {
            console.log('登录失败: 用户不存在 -', username);
            return res.status(404).json({ error: 'User not found' });
        }
        
        // 验证密码
        if (user.password !== password) {
            console.log('登录失败: 密码错误 -', username);
            return res.status(401).json({ error: 'Invalid password' });
        }

        console.log('用户登录成功:', username, 'ID:', user.id);
        res.json(user);
    } catch (error) {
        console.error('登录失败:', error);
        res.status(400).json({ error: error.message });
    }
});

app.get('/api/messages/undelivered/:userId', async (req, res) => {
    try {
        const messages = await Message.findAll({
            where: {
                receiverId: req.params.userId,
                isDelivered: false
            },
            include: [
                { model: User, as: 'sender' },
                { model: User, as: 'receiver' }
            ]
        });
        res.json(messages);
    } catch (error) {
        console.error('获取未读消息失败:', error);
        res.status(400).json({ error: error.message });
    }
});

// 获取用户的消息历史
app.get('/api/messages/history/:userId', async (req, res) => {
    try {
        const page = parseInt(req.query.page) || 1;
        const limit = parseInt(req.query.limit) || 50;
        const offset = (page - 1) * limit;
        const targetUserId = parseInt(req.query.targetUserId);

        const messages = await Message.findAll({
            where: {
                [Op.or]: [
                    {
                        [Op.and]: [
                            { senderId: req.params.userId },
                            { receiverId: targetUserId }
                        ]
                    },
                    {
                        [Op.and]: [
                            { senderId: targetUserId },
                            { receiverId: req.params.userId }
                        ]
                    }
                ]
            },
            include: [
                { model: User, as: 'sender', attributes: ['username'] },
                { model: User, as: 'receiver', attributes: ['username'] }
            ],
            attributes: {
                include: [
                    'id',
                    'content',
                    'type',
                    'timestamp',
                    'quotedMessageId',
                    'quotedContent',
                    'quotedSenderName',
                    'isRead',
                    'readTime'
                ]
            },
            order: [['timestamp', 'DESC']],
            limit: limit,
            offset: offset
        });
        console.log(`获取用户 ${req.params.userId} 与用户 ${targetUserId} 的消息历史，第 ${page} 页，每页 ${limit} 条，共 ${messages.length} 条`);
        res.json(messages);
    } catch (error) {
        console.error('获取消息历史失败:', error);
        res.status(400).json({ error: error.message });
    }
});

app.get('/api/users/:userId', async (req, res) => {
    try {
        const user = await User.findByPk(req.params.userId);
        if (!user) {
            return res.status(404).json({ error: 'User not found' });
        }
        res.json(user);
    } catch (error) {
        console.error('获取用户信息失败:', error);
        res.status(500).json({ error: error.message });
    }
});

// 更新用户最后活动时间
app.post('/api/users/:userId/last-seen', async (req, res) => {
    try {
        const user = await User.findByPk(req.params.userId);
        if (!user) {
            return res.status(404).json({ error: 'User not found' });
        }
        // 使用UTC时间
        const now = new Date();
        now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
        await user.update({ lastSeen: now.toISOString() });
        console.log(`用户 ${user.username} 的最后活动时间已更新为: ${now.toISOString()}`);
        res.json(user);
    } catch (error) {
        console.error('更新最后活动时间失败:', error);
        res.status(500).json({ error: error.message });
    }
});

// 修改密码路由
app.post('/api/users/:userId/change-password', async (req, res) => {
    try {
        const { oldPassword, newPassword } = req.body;
        const userId = req.params.userId;

        // 查找用户
        const user = await User.findByPk(userId);
        if (!user) {
            console.log('修改密码失败: 用户不存在 - ID:', userId);
            return res.status(404).json({ error: 'User not found' });
        }

        // 验证旧密码
        if (user.password !== oldPassword) {
            console.log('修改密码失败: 当前密码错误 - 用户:', user.username);
            return res.status(401).json({ error: 'Invalid old password' });
        }

        // 更新密码
        await user.update({ password: newPassword });
        console.log('密码修改成功 - 用户:', user.username);
        res.json(user);
    } catch (error) {
        console.error('修改密码失败:', error);
        res.status(500).json({ error: error.message });
    }
});

// 修改图片上传路由使用新的imageUpload中间件
app.post('/api/upload', imageUpload.single('image'), (req, res) => {
    try {
        if (!req.file) {
            return res.status(400).json({ error: '没有文件被上传' });
        }
        // 返回图片URL
        const imageUrl = `http://${req.get('host')}/uploads/${req.file.filename}`;
        res.json({ imageUrl: imageUrl });
    } catch (error) {
        console.error('文件上传失败:', error);
        res.status(500).json({ error: '文件上传失败' });
    }
});

// 添加音频上传路由
app.post('/api/upload/audio', audioUpload.single('audio'), (req, res) => {
    try {
        if (!req.file) {
            return res.status(400).json({ error: '没有文件被上传' });
        }
        // 返回音频URL
        const audioUrl = `http://${req.get('host')}/uploads/${req.file.filename}`;
        res.json({ audioUrl: audioUrl });
    } catch (error) {
        console.error('音频上传失败:', error);
        res.status(500).json({ error: '音频上传失败' });
    }
});

// 添加文件上传路由
app.post('/api/upload/file', fileUpload.single('file'), (req, res) => {
    try {
        console.log('收到文件上传请求');
        
        if (!req.file) {
            console.error('文件上传失败: 没有接收到文件');
            return res.status(400).json({ error: '没有文件被上传' });
        }

        console.log('文件信息:', {
            originalName: req.file.originalname,
            size: req.file.size,
            mimetype: req.file.mimetype,
            filename: req.file.filename
        });

        // 确保上传目录存在
        const uploadDir = 'uploads/';
        if (!fs.existsSync(uploadDir)) {
            fs.mkdirSync(uploadDir, { recursive: true });
        }

        // 获取原始文件名
        const originalName = req.file.originalname;
        // 获取文件大小
        const fileSize = req.file.size;
        // 返回文件URL和信息
        const fileUrl = `http://${req.get('host')}/uploads/${req.file.filename}`;
        
        console.log('文件上传成功:', {
            fileUrl: fileUrl,
            fileName: originalName,
            fileSize: fileSize
        });

        res.json({ 
            fileUrl: fileUrl,
            fileName: originalName,
            fileSize: fileSize
        });
    } catch (error) {
        console.error('文件上传失败，详细错误:', error);
        if (error instanceof multer.MulterError) {
            // Multer错误处理
            if (error.code === 'LIMIT_FILE_SIZE') {
                return res.status(400).json({ error: '文件大小超过限制(100MB)' });
            }
            return res.status(400).json({ error: `文件上传错误: ${error.message}` });
        }
        res.status(500).json({ error: '文件上传失败: ' + error.message });
    }
});

// 添加视频上传路由
app.post('/api/upload/video', videoUpload.single('video'), (req, res) => {
    try {
        console.log('收到视频上传请求');
        
        if (!req.file) {
            console.error('视频上传失败: 没有接收到文件');
            return res.status(400).json({ error: '没有文件被上传' });
        }

        console.log('视频信息:', {
            originalName: req.file.originalname,
            size: req.file.size,
            mimetype: req.file.mimetype,
            filename: req.file.filename
        });

        // 确保上传目录存在
        const uploadDir = 'uploads/';
        if (!fs.existsSync(uploadDir)) {
            fs.mkdirSync(uploadDir, { recursive: true });
        }

        // 返回视频URL
        const videoUrl = `http://${req.get('host')}/uploads/${req.file.filename}`;
        
        console.log('视频上传成功:', {
            videoUrl: videoUrl
        });

        res.json({ videoUrl: videoUrl });
    } catch (error) {
        console.error('视频上传失败，详细错误:', error);
        if (error instanceof multer.MulterError) {
            // Multer错误处理
            if (error.code === 'LIMIT_FILE_SIZE') {
                return res.status(400).json({ error: '文件大小超过限制(200MB)' });
            }
            return res.status(400).json({ error: `视频上传错误: ${error.message}` });
        }
        res.status(500).json({ error: '视频上传失败: ' + error.message });
    }
});

// 检查更新接口
app.get('/api/update/check', (req, res) => {
    const currentVersion = parseInt(req.query.version_code) || 0;
    
    if (currentVersion < updateConfig.latestVersion) {
        // 需要更新
        res.json(updateConfig);
    } else {
        // 已是最新版本
        res.status(304).send();
    }
});

// 获取下载地址接口
app.get('/api/update/download', (req, res) => {
    const targetVersion = parseInt(req.query.version_code) || 0;
    
    if (targetVersion === updateConfig.latestVersion) {
        res.json({
            url: updateConfig.downloadUrl
        });
    } else {
        res.status(400).json({
            error: "Invalid version code"
        });
    }
});

// 下载APK文件的接口
app.get('/downloads/:filename', (req, res) => {
    const filename = req.params.filename;
    const filePath = path.join(__dirname, 'downloads', filename);
    
    // 检查文件是否存在
    if (fs.existsSync(filePath)) {
        // 获取文件信息
        const stat = fs.statSync(filePath);
        // 更新配置中的文件大小
        updateConfig.apkSize = stat.size;
        
        // 计算文件的MD5
        const fileBuffer = fs.readFileSync(filePath);
        const hashSum = crypto.createHash('md5');
        hashSum.update(fileBuffer);
        updateConfig.apkMd5 = hashSum.digest('hex');
        
        // 保存更新后的配置
        fs.writeFileSync(
            path.join(__dirname, 'config', 'update.json'),
            JSON.stringify(updateConfig, null, 4)
        );
        
        res.download(filePath);
    } else {
        res.status(404).json({
            error: "File not found"
        });
    }
});

// 朋友圈相关路由
app.get('/api/moments', async (req, res) => {
    try {
        const page = parseInt(req.query.page) || 1;
        const limit = parseInt(req.query.limit) || 10;
        const offset = (page - 1) * limit;

        const { count, rows: moments } = await Moment.findAndCountAll({
            include: [
                {
                    model: User,
                    attributes: ['username']
                }
            ],
            order: [['createdAt', 'DESC']],
            limit: limit,
            offset: offset
        });

        res.json({
            moments: moments,
            total: count,
            currentPage: page,
            totalPages: Math.ceil(count / limit)
        });
    } catch (error) {
        console.error('获取朋友圈列表失败:', error);
        res.status(500).json({ error: '获取朋友圈列表失败' });
    }
});

app.post('/api/moments', async (req, res) => {
    try {
        const { userId, content, images } = req.body;
        const moment = await Moment.create({
            userId,
            content,
            images
        });
        const momentWithUser = await Moment.findOne({
            where: { id: moment.id },
            include: [
                {
                    model: User,
                    attributes: ['username']
                }
            ]
        });
        res.json(momentWithUser);
    } catch (error) {
        console.error('发布朋友圈失败:', error);
        res.status(500).json({ error: '发布朋友圈失败' });
    }
});

app.post('/api/moments/:momentId/like', async (req, res) => {
    try {
        const { momentId } = req.params;
        const { userId } = req.body;
        
        const moment = await Moment.findByPk(momentId);
        if (!moment) {
            return res.status(404).json({ error: '动态不存在' });
        }

        // 检查是否已经点赞
        const likes = moment.likes || [];
        const existingLike = likes.find(like => like.userId === userId);
        
        if (existingLike) {
            // 如果已经点赞，则取消点赞
            moment.likes = likes.filter(like => like.userId !== userId);
        } else {
            // 如果未点赞，则添加点赞
            const user = await User.findByPk(userId);
            moment.likes = [...likes, { userId, username: user.username }];
        }
        
        await moment.save();
        
        const updatedMoment = await Moment.findOne({
            where: { id: momentId },
            include: [
                {
                    model: User,
                    attributes: ['username']
                }
            ]
        });
        
        res.json(updatedMoment);
    } catch (error) {
        console.error('点赞操作失败:', error);
        res.status(500).json({ error: '点赞操作失败' });
    }
});

app.post('/api/moments/:momentId/comments', async (req, res) => {
    try {
        const { momentId } = req.params;
        const { userId, content } = req.body;
        
        const moment = await Moment.findByPk(momentId);
        if (!moment) {
            return res.status(404).json({ error: '动态不存在' });
        }

        const user = await User.findByPk(userId);
        const comments = moment.comments || [];
        
        // 添加新评论
        const newComment = {
            id: comments.length + 1,
            userId,
            username: user.username,
            content,
            timestamp: new Date().toISOString()
        };
        
        moment.comments = [...comments, newComment];
        await moment.save();
        
        const updatedMoment = await Moment.findOne({
            where: { id: momentId },
            include: [
                {
                    model: User,
                    attributes: ['username']
                }
            ]
        });
        
        res.json(updatedMoment);
    } catch (error) {
        console.error('评论失败:', error);
        res.status(500).json({ error: '评论失败' });
    }
});

app.delete('/api/moments/:momentId', async (req, res) => {
    try {
        const { momentId } = req.params;
        const moment = await Moment.findByPk(momentId);
        
        if (!moment) {
            return res.status(404).json({ error: '动态不存在' });
        }
        
        await moment.destroy();
        res.status(200).send();
    } catch (error) {
        console.error('删除动态失败:', error);
        res.status(500).json({ error: '删除动态失败' });
    }
});

// 获取用户最新消息的API
app.get('/api/messages/latest/:userId', async (req, res) => {
    try {
        const userId = parseInt(req.params.userId);
        const latestMessage = await Message.findOne({
            where: {
                [Op.or]: [
                    { senderId: userId },
                    { receiverId: userId }
                ]
            },
            order: [['createdAt', 'DESC']]
        });
        
        res.json(latestMessage || null);
    } catch (error) {
        console.error('获取最新消息失败:', error);
        res.status(500).json({ error: error.message });
    }
});

// 清理聊天记录的函数
async function cleanupOldMessages() {
    try {
        console.log('\n开始清理旧数据...');
        
        // 获取7天前的时间戳
        const sevenDaysAgo = new Date();
        sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
        
        // 1. 清理旧消息
        // 查询要删除的消息数量
        const messageCount = await Message.count({
            where: {
                timestamp: {
                    [Op.lt]: sevenDaysAgo
                }
            }
        });
        
        if (messageCount > 0) {
            // 1.1 先找出所有7天前的消息ID
            const oldMessages = await Message.findAll({
                attributes: ['id'],
                where: {
                    timestamp: {
                        [Op.lt]: sevenDaysAgo
                    }
                }
            });
            const oldMessageIds = oldMessages.map(msg => msg.id);

            // 1.2 更新所有引用这些旧消息的消息
            await Message.update(
                { 
                    quotedMessageId: null,
                    quotedContent: '原消息已被清理',
                    quotedSenderName: null
                },
                {
                    where: {
                        quotedMessageId: {
                            [Op.in]: oldMessageIds
                        }
                    }
                }
            );

            // 1.3 删除7天前的消息
            const messageResult = await Message.destroy({
                where: {
                    id: {
                        [Op.in]: oldMessageIds
                    }
                }
            });
            console.log(`已删除 ${messageResult} 条7天前的消息`);
        } else {
            console.log('没有需要清理的旧消息');
        }

        // 2. 清理旧朋友圈记录
        const momentCount = await Moment.count({
            where: {
                timestamp: {
                    [Op.lt]: sevenDaysAgo
                }
            }
        });

        if (momentCount > 0) {
            // 删除7天前的朋友圈记录
            const momentResult = await Moment.destroy({
                where: {
                    timestamp: {
                        [Op.lt]: sevenDaysAgo
                    }
                }
            });
            console.log(`已删除 ${momentResult} 条7天前的朋友圈`);
        } else {
            console.log('没有需要清理的旧朋友圈');
        }
        
        // 3. 清理无用的上传文件（包括消息和朋友圈的图片、音频、视频等文件）
        const uploadsDir = 'uploads/';
        if (fs.existsSync(uploadsDir)) {
            const files = fs.readdirSync(uploadsDir);
            let deletedFiles = 0;
            
            for (const file of files) {
                const filePath = path.join(uploadsDir, file);
                const stats = fs.statSync(filePath);
                const fileAge = (new Date() - stats.mtime) / (1000 * 60 * 60 * 24); // 转换为天数
                
                if (fileAge > 7) {
                    fs.unlinkSync(filePath);
                    deletedFiles++;
                }
            }
            
            if (deletedFiles > 0) {
                console.log(`已删除 ${deletedFiles} 个7天前的上传文件`);
            }
        }

        console.log('数据清理任务完成');
    } catch (error) {
        console.error('清理旧数据时出错:', error);
    }
}

// 设置定时清理任务
function setupCleanupTask() {
    // 立即执行一次清理
    cleanupOldMessages();
    
    // 设置每天凌晨3点执行清理
    const now = new Date();
    const night = new Date(
        now.getFullYear(),
        now.getMonth(),
        now.getDate() + 1, // 明天
        3, // 凌晨3点
        0,
        0
    );
    
    // 计算到凌晨3点的毫秒数
    let delay = night.getTime() - now.getTime();
    if (delay < 0) {
        delay += 24 * 60 * 60 * 1000; // 如果今天的3点已经过了，就等到明天3点
    }
    
    // 设置首次执行的定时器
    setTimeout(() => {
        cleanupOldMessages();
        // 设置每24小时执行一次的定时器
        setInterval(cleanupOldMessages, 24 * 60 * 60 * 1000);
    }, delay);
    
    console.log(`消息自动清理任务已设置，将在每天凌晨3点执行`);
}

// 启动服务器
async function startServer() {
    try {
        // 同步数据库模型，禁用自动创建索引
        await sequelize.sync({ 
            alter: true,
            indexes: false // 禁用自动创建索引
        });
        console.log('数据库同步完成');
        
        // 设置清理任务
        setupCleanupTask();
        
        udpServer.bind(UDP_PORT, () => {
            console.log(`UDP服务器运行在端口 ${UDP_PORT}`);
        });

        app.listen(PORT, () => {
            console.log(`HTTP服务器运行在端口 ${PORT}`);
        });
    } catch (error) {
        console.error('启动服务器失败:', error);
        process.exit(1);
    }
}

// 处理进程退出
process.on('SIGINT', async () => {
    try {
        await sequelize.close();
        console.log('数据库连接已关闭');
        process.exit(0);
    } catch (error) {
        console.error('关闭数据库连接失败:', error);
        process.exit(1);
    }
});

startServer(); 